﻿using Abp.Configuration;
using Abp.Configuration.Startup;
using Exceptionless;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using MyCompanyName.AbpZeroTemplate.Configuration;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;

namespace Abp.Settings
{
    public class ExceptionlessSettingProvider : SettingProvider
    {
        static readonly Dictionary<string, Type> keys = new Dictionary<string, Type>();
        static readonly string KEY_Prefix = $"{nameof(Exceptionless)}.";

        public IConfigurationRoot Configuration { get; }

        static ExceptionlessSettingProvider()
        {
            keys = typeof(ExceptionlessConfiguration).GetProperties()
                .Where(x => x.CanRead && x.CanWrite)
                .Where(x => x.PropertyType.IsValueType || x.PropertyType == typeof(string))
                 .ToDictionary(x => x.Name, x => x.PropertyType);
        }

        public ExceptionlessSettingProvider(IAppConfigurationAccessor configurationAccessor)
        {
            Configuration = configurationAccessor.Configuration;
        }

        public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)
        {
            var allSettings = keys.Keys.Select(x =>
             {
                 var itemType = keys[x];
                 string value = GetFromSettings(x);
                 string key = $"{KEY_Prefix}{x}";
                 if (!string.IsNullOrEmpty(value))
                 {
                     if (itemType.IsValueType)
                     {
                         return new SettingDefinition(key, $"\"{value}\"");
                     }
                     else if (itemType == typeof(string))
                     {
                         return new SettingDefinition(key, value);
                     }
                 }
                 if (itemType.IsValueType)
                 {
                     return new SettingDefinition(key, null);
                 }
                 else
                 {
                     return new SettingDefinition(key, null);
                 }
             })
                .ToList();
            {
                string key = $"{KEY_Prefix}{nameof(ExceptionlessConfiguration.Settings)}";
                if (!allSettings.Any(x => x.Name == key))
                {
                    string value = GetFromSettingsDict(nameof(ExceptionlessConfiguration.Settings), "{}");
                    allSettings.Add(new SettingDefinition(key, value));
                }
            }
            return allSettings;
        }

        public const string MinLogLevel = "MinLogLevel";
        public const string ConsoleLogLevel = "ConsoleLogLevel";

        private string GetFromSettings(string name, string defaultValue = null)
        {
            string key = $"{nameof(Exceptionless)}:{name}";
            return Configuration[key] ?? defaultValue;
        }
        private string GetFromSettingsDict(string name, string defaultValue = null)
        {
            string key = $"{nameof(Exceptionless)}:{name}";
            var section = Configuration.GetSection(key);
            if (section == null) return null;
            if (!string.IsNullOrEmpty(section.Value))
            {
                return section.Value;
            }
            var children = section.GetChildren();
            Dictionary<string, string> dict = new Dictionary<string, string>();
            foreach (var s in children)
            {
                if (s.Key.Contains("-"))
                {
                    dict.Add(s.Key.Replace("-", ":"), s.Value);
                }
                else
                {
                    dict.Add(s.Key, s.Value);
                }
            }
            return JsonConvert.SerializeObject(dict);
        }
    }
}
